package com.zhj.juc.demo13;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

/**
 * @PackageName:com.zhj.juc.demo13
 * @ClassName:Test3LazyMan
 * @auter: 朱慧杰
 * @date:2020/7/25 0025 9:36
 **/
public class Test3LazyMan {

    private static boolean zhj = false;
    // 懒汉式
    private Test3LazyMan () {
        synchronized (Test3LazyMan.class){
            if (zhj == false) {
                zhj =true;
            }else {
                throw new RuntimeException("不要用反射去试图破坏单例！");
            }
            /*if (lazyMan != null) {
                throw new RuntimeException("不要用反射去试图破坏单例！");
            }*/
        }
        // System.out.println(Thread.currentThread().getName());
    }

    private volatile static Test3LazyMan lazyMan;

    public static Test3LazyMan getInstance() {

        // 双重检测锁模式，懒汉式单例，DCL
        if (lazyMan == null) {
            synchronized (Test3LazyMan.class) {
                if (lazyMan == null) {
                    lazyMan = new Test3LazyMan(); // 不是一个原子性的
                    /**
                     * 1. 分配内存空间
                     * 2. 执行构造初始化对象
                     * 3. 把这个对象指向这个空间
                     */
                }
            }
            // lazyMan = new Test3LazyMan();
        }
        return lazyMan;
    }

    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                Test3LazyMan.getInstance();
            }).start();
        }

        Field zhj = Test3LazyMan.class.getDeclaredField("zhj");
        zhj.setAccessible(true);
        // Test3LazyMan instance = Test3LazyMan.getInstance();
        Constructor<Test3LazyMan> declaredConstructor = Test3LazyMan.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);
        Test3LazyMan instance = declaredConstructor.newInstance();
        zhj.set(instance,false);
        Test3LazyMan instance2 = declaredConstructor.newInstance();
        System.out.println(instance);
        System.out.println(instance2);
    }

}
